#ifndef __UAPI_USB__
#define __UAPI_USB__

#include <stdint.h>
#include <libusb.h>

#ifdef __cplusplus
extern "C" {
#endif

#define UAPI_BULK_IO_PHASE_IN          0x80
#define UAPI_BULK_IO_PHASE_OUT         0x00
#define UAPI_BULK_TRANSFER_TIMEOUT 5000
#define UAPI_BULK_ACK_LEN            4

#define UAPI_ZERO_OUT_ENDPOINT            0
#define UAPI_ONE_IN_ENDPOINT            0x81
#define UAPI_ENDPOINT_DIR_MASK          0x80



#define UAPI_ENDPOINT_NUM_MAX    15  //usb端点号最大值

enum uapi_endpoint_direction {
    /** Out: host-to-device */
    UAPI_ENDPOINT_OUT = 0x00,
    /** In: device-to-host */
    UAPI_ENDPOINT_IN = 0x80
};

enum uapi_usb_error {
    UAPI_SUCCESS = 0,
    UAPI_ERROR_IO = -1,
    UAPI_ERROR_INVALID_PARAM = -2,
    UAPI_ERROR_ACCESS = -3,
    UAPI_ERROR_NO_DEVICE = -4,
    UAPI_ERROR_NOT_FOUND = -5,
    UAPI_ERROR_BUSY = -6,
    UAPI_ERROR_TIMEOUT = -7,
    UAPI_ERROR_OVERFLOW = -8,
    UAPI_ERROR_PIPE = -9,
    UAPI_ERROR_INTERRUPTED = -10,
    UAPI_ERROR_NO_MEM = -11,
    UAPI_ERROR_NOT_SUPPORTED = -12,
    UAPI_ERROR_TRANSFER  =-13,
    UAPI_ERROR_TRANSFER_LEN =-14,
    UAPI_ERROR_ACK =-15,

    UAPI_ERROR_OTHER = -99
};

typedef struct {
    libusb_device_handle *handle;
    uint8_t endpoint_in;
    uint8_t endpoint_out;
    uint8_t interface_number;
} uapi_usb_handle;


typedef struct
{
    uint8_t *buf;
    uint32_t need_write_len;
    uint32_t need_read_len;
    uint32_t actual_write_len;
    uint32_t actual_read_len;
    uint32_t timeout;
} uapi_usb_cmd;
extern libusb_context *g_usb_ctx;

int32_t uapi_usb_init(void);
void uapi_usb_exit(void);
int32_t uapi_open_usb_handle_by_vid(uint16_t vendor_id, uapi_usb_handle *handle);
void uapi_close_usb_handle(uapi_usb_handle *handle);
int32_t uapi_usb_recv_msg(uapi_usb_handle *handle, uint8_t *buf, uint32_t len);
int32_t uapi_usb_send_msg(uapi_usb_handle *        handle, uint8_t *buf, uint32_t len);
int32_t uapi_usb_bulk_transfer(uapi_usb_handle *        handle, uapi_usb_cmd *cmd);


#ifdef __cplusplus
}
#endif

#endif

